package com.ovopark.organize.server.util;


import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;

/**
 * 时间转换工具类
 * @author huanglt
 */
public class DateUtils extends org.apache.commons.lang.time.DateUtils{
	/** 用连字符.分隔的时间格式串，如yyyy.MM.dd */
	public static final String LINK_DISPLAY_DATE_DOT = "yyyy.MM.dd";
	/** 用连字符-分隔的时间格式串，如yyyy-MM-dd */
	public static final String LINK_DISPLAY_DATE = "yyyy-MM-dd";
	/** 用连字符-分隔的时间格式串，如yyyy-MM-dd */
	public static final String LINK_DISPLAY_DATE_SLASH = "yyyy/MM/dd";

	/** 用连字符-分隔的时间格式串，如yyyy-MM-dd HH:Mi:SS */
	public static final String LINK_DISPLAY_DATE_FULL = "yyyy-MM-dd HH:mm:ss";

	/** 用连字符-分隔的时间格式串，如yyyy-MM */
	public static final String LINK_DISPLAY_DATE_MONTH = "yyyy-MM";
	public static final String LINK_DISPLAY_DATE_MONTH_SHORT = "yy-MM";
	/** 用连字符-分隔的时间格式串，如yyyy-MM-dd HH */
	public static final String LINK_DISPLAY_DATE_HOURS = "yyyy-MM-dd HH";
	/** 用连字符-分隔的时间格式串，如yyyy-MM-dd HH */
	public static final String LINK_DISPLAY_DATE_MINUTE = "yyyy-MM-dd HH:mm";
	
	/** 显示 时-分-秒 字符串*/
	public static final String LINK_DISPLAY_DATE_HMS = "HH:mm:ss";
	
	/** 显示 时-分-秒 字符串*/
	public static final String LINK_DISPLAY_TIME_HM = "HH:mm";
	
	public static final String LINK_DATABASE_DATE_FUll = "yyyyMMddHHmmss";
	public static final String LINK_DATABASE_DATE_MSEL= "yyyyMMddHHmmssSSS";
	
	public static final int TIME_MINUTE = 0;
	public static final int TIME_HOUR = 1;
	public static final int TIME_DAY = 2;
	public static final int TIME_WEEK = 3; // 周统计
	public static final int TIME_MONTH = 4;
	public static final int TIME_QUARTER = 5;
	public static final int TIME_YEAR = 6;
	public static final int WEEK_DAY = 7;  // 周日，周一 ...
	public static final int TIME_WEEK_FIRST_DAY = 8;  // 周的第一天
	public static final int TIME_DAY_FULL = 9;
	public static final int TIME_DATE= 10;
	public static final int TIME_MONTH_FULL= 11;
	public static final int TIME_QUARTER_FULL= 12;
	public static final int TIME_YEAR_FULL= 13;
	/**
	 * 获取两日期之间的时间差
	 * @param stratDate
	 * @param endDate
	 * @return
	 * @author huanglt
	 */
	public static long  getTimeDifBetweenTwoDate(Date stratDate,Date endDate){
		long stratDateTime = stratDate.getTime();
		long endDateTime =endDate.getTime();
		return stratDateTime-endDateTime;
	}
	/**
	 * 获取当前年份，月份，或日
	 * @param timeType
	 * @return
	 * @author huanglt
	 */
	public static int  getCurrentTimeFlag(int timeType){
		int output = 0;
		Calendar cal = Calendar.getInstance();
		switch (timeType) {
		case DateUtils.TIME_YEAR:
			// 以分钟为单位
			output = cal.get(Calendar.YEAR);
			break;
		case DateUtils.TIME_MONTH:
			// 以小时为时间单位综合
			output = cal.get(Calendar.MONTH) + 1;
			break;
		case DateUtils.TIME_DAY:
			output =  cal.get(Calendar.DATE);
			break;
		case DateUtils.TIME_HOUR:
			output =  cal.get(Calendar.HOUR_OF_DAY);
			break;
		}
		return output;
	}
	/**
	 * 得到格式化时间串
	 *
	 * @param date
	 *            指定时间
	 * @param
	 *
	 * @return 指定时间的格式化时间串
	 * @author huanglt
	 */
	public static String getDateStr(Date date) {
		SimpleDateFormat format = new SimpleDateFormat(LINK_DISPLAY_DATE_FULL);
		return format.format(date);
	}
	/**
	 * 得到格式化时间串
	 *
	 * @param date
	 *            指定时间
	 * @param
	 *
	 * @return 指定时间的格式化时间串
	 * @author huanglt
	 */
	public static String getDateStr(Date date, String formatStr) {
		SimpleDateFormat fomate = new SimpleDateFormat(formatStr);
		return fomate.format(date);
	}
	/**
	 * 得到某天的开始时间
	 * @param date
	 * @return 指定时间的格式化时间串
	 * @author huanglt
	 */
	public static Date getDateStart(Date date) {
		 String dateStartStr =  DateUtils.getDateStr(date, DateUtils.LINK_DISPLAY_DATE)+ " 00:00:00";
		 return DateUtils.StringToDate(dateStartStr, DateUtils.LINK_DISPLAY_DATE_FULL);
	}
	/**
	 * 得到某天的结束时间
	 * @param date
	 * @return 指定时间的格式化时间串
	 * @author huanglt
	 */
	public static Date getDateEnd(Date date) {
		 String dateEndStr =  DateUtils.getDateStr(date, DateUtils.LINK_DISPLAY_DATE)+ " 23:59:59";
		 return DateUtils.StringToDate(dateEndStr, DateUtils.LINK_DISPLAY_DATE_FULL);
	}
	
	/**
	 * 得到某天的开始时间
	 * @param date
	 * @return 指定时间的格式化时间串
	 * @author huanglt
	 */
	public static String getDateStartStr(Date date) {
		return DateUtils.getDateStr(date, DateUtils.LINK_DISPLAY_DATE)+ " 00:00:00";
	}
	/**
	 * 得到某天的结束时间
	 * @param date
	 * @return 指定时间的格式化时间串
	 * @author huanglt
	 */
	public static String getDateEndStr(Date date) {
		return DateUtils.getDateStr(date, DateUtils.LINK_DISPLAY_DATE)+ " 23:59:59";
	}
	/**
	 * 获取当前日期
	 * @return
	 * @author huanglt
	 */
	public static Date getNowDate() {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(LINK_DISPLAY_DATE);
			Date nowDate = sdf.parse(sdf.format(new Date()));
			return nowDate;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 获取当前时间
	 * @return
	 * @author huanglt
	 */
	public static Date getCurrentTime() {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(LINK_DISPLAY_DATE_FULL);
			Date nowDate = sdf.parse(sdf.format(new Date()));
			return nowDate;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 获取当前时间
	 * @return
	 * @author huanglt
	 */
	public static Date getCurrentTime(TimeZone timeZone) {
		// 默认东八区
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MILLISECOND, timeZone.getRawOffset() - TimeZone.getDefault().getRawOffset());
		return cal.getTime();
	}
	/**
	 * 获取当前时间字符串
	 * @return
	 * @author huanglt
	 */
	public static String getCurrentTimeStr() {
		return getDateStr(new Date(),LINK_DATABASE_DATE_MSEL);
	}
	/**
	 * 获取时间到小时
	 * @param date
	 * @return
	 * @author huanglt
	 */
	public static Date getHour(Date date) {
		SimpleDateFormat fomate = new SimpleDateFormat(LINK_DISPLAY_DATE_HOURS);
		String dateStr =fomate.format(date);
		try {
			Date hour =  fomate.parse(dateStr);
			return hour;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 获取时间到分钟
	 * @param date
	 * @return
	 * @author huanglt
	 */
	public static Date getM(Date date) {
		SimpleDateFormat fomate = new SimpleDateFormat(LINK_DISPLAY_DATE_MINUTE);
		String dateStr =fomate.format(date);
		try {
			Date hour =  fomate.parse(dateStr);
			return hour;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 获取指定日期的时分秒
	 * @param date
	 * @return
	 * @author huanglt
	 */
	public static String getDateHMS(Date date) {
		return getDateStr(date,LINK_DISPLAY_DATE_HMS);
	}
	/**
	 * 将指点字符传时间转为Date格式
	 * @param strDate 传入时间 e.g(2014-11-11 12:10:12)
	 * @param format  格式化   "yyyy-MM-dd HH:mm:ss"
	 * @return
	 * @author huanglt
	 */
    public static Date StringToDate(String strDate, String format){
    	SimpleDateFormat sdf = new SimpleDateFormat(format);
    	Date date;
		try {
		  return date = sdf.parse(strDate);
		} catch (ParseException e) {
			e.printStackTrace();
		}
    	  return null;
    }
    /**
     * 日期指定格式转换
     * @param date   传入时间
     * @param format 格式化
     * @return
     * @author huanglt
     */
    public static Date praseDateToDatePattern(Date date, String format){
    	  String  resultDate = getDateStr(date,format);
    	  return StringToDate(resultDate,format);
    }
    /**
     * 日期指定格式转换
     * @param date   传入时间
     * @param format 格式化
     * @return
     * @author huanglt
     */
    public static String praseStringtoStringPattern(String date, String format){
    	   Date  resultDate = StringToDate(date,format);
    	  return getDateStr(resultDate,format);
    }
    /**
     * 日期指定格式转换
     * @param date   传入时间
     * @param
     * @return
     * @author huanglt
     */
    public static String praseStringtoStringPattern(String date,String inputFormat, String outputFormat){
    	   Date  resultDate = StringToDate(date,inputFormat);
    	  return getDateStr(resultDate,outputFormat);
    }
	/**
	 * 判断日期是否为今天
	 * @param compareDate 比较日期 
	 * @return
	 * @author huanglt
	 */
	public static boolean isToday(Date compareDate){
		  Calendar compareCalendar = Calendar.getInstance();
		  compareCalendar.setTime(praseDateToDatePattern(compareDate,LINK_DISPLAY_DATE));
		  Calendar todayCalendar = Calendar.getInstance();
		  todayCalendar.setTime(DateUtils.getNowDate());
		  long l=compareCalendar.getTimeInMillis()-todayCalendar.getTimeInMillis();
		  int days=new Long(l/(1000*60*60*24)).intValue();
		  if(days==0){
			  return true;
		  }else{
			  return false;
		  }
	}
	
    /**
     * 获取各种不同时间的显示格式
     * @param dateStr
     * @param timeType
     * @return
     * @author huanglt
     */
	public static String getShowTimeStr(String dateStr, int timeType) {
		String output = null;
		SimpleDateFormat sdf = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			date = sdf.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		switch (timeType) {
		case DateUtils.TIME_MINUTE:
			// 以分钟为单位
			output = dateStr.substring(11, 16);
			break;
		case DateUtils.TIME_HOUR:
			// 以小时为时间单位综合
			output = dateStr.substring(11, 16);
			break;
		case DateUtils.TIME_DAY:
			output = dateStr.substring(5, 10);
			break;
		case DateUtils.TIME_DAY_FULL:
			output = dateStr;
			break;
		case DateUtils.TIME_DATE:
			output = dateStr.substring(0, 10);
			break;
		case DateUtils.TIME_WEEK:
			if(cal.get(Calendar.WEEK_OF_YEAR)==1){
				output = cal.get(Calendar.YEAR)+1 +"年第" + cal.get(Calendar.WEEK_OF_YEAR) + "周";
			}else{
				output = cal.get(Calendar.YEAR) +"年第" + cal.get(Calendar.WEEK_OF_YEAR) + "周";
			}
			
			break;
		case DateUtils.TIME_MONTH:
			// 以月为单位综合
			int month = cal.get(Calendar.MONTH) + 1;
			String year = cal.get(Calendar.YEAR) + "";
			String monthStr = month < 10 ? "0" + month : "" + month;
			output =year.substring(2, year.length())+"-"+monthStr;
			break;
		case DateUtils.TIME_MONTH_FULL:
			// 以月为单位综合
			output = getDateStr(getFirstDayOfMonth(date),DateUtils.LINK_DISPLAY_DATE_FULL);
			break;
		case DateUtils.TIME_QUARTER:
			output =  cal.get(Calendar.YEAR) +"年第" + (cal.get(Calendar.MONTH) / 3 + 1) + "季度";
			break;
		case DateUtils.TIME_YEAR:
			output = cal.get(Calendar.YEAR) + "";
			break;
		case DateUtils.TIME_YEAR_FULL:
			output = cal.get(Calendar.YEAR) + "";
			break;
		case DateUtils.TIME_WEEK_FIRST_DAY:
			// 以年为单位综合
			output = getDateStr(getFirstDayOfWeek(cal.getTime()),DateUtils.LINK_DISPLAY_DATE);
			break;
		default:
			// 以小时为时间单位综合
			output = dateStr.substring(11, 16);
		}
		return output;
	}
	
	    /**
	     * 获取指定时间类型的第一天
	     * @param
	     * @param timeType
	     * @return
	     * @author huanglt
	     */
		public static String getFirstDayStr(Date date, int timeType) {
			String output = null;
			if(date==null){
				return output;
			}		
			switch (timeType) {
			case DateUtils.TIME_MINUTE:// 以分钟为单位
			case DateUtils.TIME_HOUR:// 以小时为时间单位综合
			case DateUtils.TIME_DAY:
				output = DateUtils.getDateStr(date, DateUtils.LINK_DISPLAY_DATE)+ " 00:00:00";
				break;
			case DateUtils.TIME_WEEK:
				output = DateUtils.getFirstDayStrOfWeek(date)+ " 00:00:00";
				break;
			case DateUtils.TIME_MONTH:
				// 以月为单位综合
				output = DateUtils.getFirstDayStrOfMonth(date)+ " 00:00:00";
				break;
			case DateUtils.TIME_QUARTER:
				output = DateUtils.getFirstDayStrOfQuarter(date)+ " 00:00:00";
				break;
			case DateUtils.TIME_YEAR:
				break;
			case DateUtils.TIME_YEAR_FULL:
				output = DateUtils.getFirstDayStrOfQuarter(date)+ " 00:00:00";
				break;
			}
			return output;
		}
	
	
	/**
	 * 获取两时间范围内的数据
	 * @param stime
	 * @param etime
	 * @param timeType
	 * @return
	 * @throws
	 * @author huanglt
	 */
	public static List<String> findAllTimesInTwoDates( String stime, String etime, Integer timeType)  {
		    List<String> times = new ArrayList<String>();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date startDate = null;
			Date endDate = null;
			try {
				startDate = sdf.parse(stime);
				endDate = sdf.parse(etime);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			if(timeType==TIME_MONTH){
				startDate = getFirstDayOfMonth(startDate);
			}
			if(timeType==TIME_WEEK){
				 startDate = getFirstDayOfWeek(startDate);
			}
			Calendar cal = Calendar.getInstance();
			cal.setTime(startDate);
			while(cal.getTime().before(endDate)) {
				String dateStr = sdf.format(cal.getTime());
				String timeStr = getShowTimeStr(dateStr, timeType);
				times.add(timeStr);
				switch(timeType) {
				case DateUtils.TIME_MINUTE:
					cal.add(Calendar.MINUTE,1);
					break;
				case DateUtils.TIME_HOUR:
					cal.add(Calendar.HOUR,1);
					break;
				case DateUtils.TIME_DAY:
				case DateUtils.TIME_DAY_FULL:
				case DateUtils.TIME_DATE:
					cal.add(Calendar.DATE,1);
					break;
				case DateUtils.TIME_WEEK_FIRST_DAY:
				case DateUtils.TIME_WEEK:
					cal.add(Calendar.DATE,7);
					break;
				case DateUtils.TIME_MONTH:
				case DateUtils.TIME_MONTH_FULL:
					cal.add(Calendar.MONTH,1);
					break;
				case DateUtils.TIME_QUARTER:
					cal.add(Calendar.MONTH,3);
					break;
				case DateUtils.TIME_YEAR:
				case DateUtils.TIME_YEAR_FULL:
					cal.add(Calendar.YEAR,1);
				}
			}
		return times;
	}
	/**
	 * 获取前几周或后几周的第一天
	 * @param
	 * @param num    正数为后几周，负数为前几周
	 * @return
	 * @author huanglt
	 */
	public static String getFirstDayOfFewWeek(String dateStr,int num) {
		Date date = StringToDate(dateStr,LINK_DISPLAY_DATE);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.WEEK_OF_YEAR, num);
		return getDateStr(getFirstDayOfWeek(calendar.getTime()),LINK_DISPLAY_DATE)+" 00:00:00";
	}
    /**
     * 获取指定天所在周的第一天
     * @param date   指定日期
     * @return
     * @author huanglt
     */
	public static String getFirstDayStrOfWeek(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return getDateStr(getFirstDayOfWeek(calendar.getTime()),LINK_DISPLAY_DATE);
	}
	/**
     * 得到指定日期为第几周
     * @param date
     * @author huanglt
     */
    public static String getDayOfWeek(Date date) {
    	Calendar cal = Calendar.getInstance();
    	cal.setFirstDayOfWeek(Calendar.MONDAY);
		cal.setTime(date);
		String output = "第" + cal.get(Calendar.WEEK_OF_YEAR) + "周";
        return output;
    }
	
	/**
     * 得到某年某周的第一天
     * @param year
     * @param week
     * @return
     * @author huanglt
     */
    public static Date getFirstDayOfWeek(int year, int week) {
        week = week - 1;
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, Calendar.JANUARY);
        calendar.set(Calendar.DATE, 1);

        Calendar cal = (Calendar) calendar.clone();
        cal.add(Calendar.DATE, week * 7);

        return getFirstDayOfWeek(cal.getTime());
    }

    /**
     * 得到某年某周的最后一天
     * @param year
     * @param week
     * @return
     * @author huanglt
     */
    public static Date getLastDayOfWeek(int year, int week) {
        week = week - 1;
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, Calendar.JANUARY);
        calendar.set(Calendar.DATE, 1);
        Calendar cal = (Calendar) calendar.clone();
        cal.add(Calendar.DATE, week * 7);

        return getLastDayOfWeek(cal.getTime());
    }

    /**
     * 取得当前日期所在周的第一天(周一为起始天)
     * @param date
     * @return
     * @author huanglt
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK,
                      calendar.getFirstDayOfWeek()); // Sunday
        return calendar.getTime();
    }

    /**
     * 取得当前日期所在周的最后一天(周一为起始天)
     * @param date
     * @return
     * @author huanglt
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_WEEK,
                     calendar.getFirstDayOfWeek() + 6); // Saturday
        return calendar.getTime();
    }

    /**
     * 取得当前日期所在周的前一周最后一天
     * @param date
     * @return
     * @author huanglt
     */
    public static Date getLastDayOfLastWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return getLastDayOfWeek(calendar.get(Calendar.YEAR),
                                calendar.get(Calendar.WEEK_OF_YEAR) - 1);
    }

    /**
     * 返回指定日期的月的第一天
     * @param
     * @param
     * @return
     * @author huanglt
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),
                     calendar.get(Calendar.MONTH), 1);
        return getDateStart(calendar.getTime());
    }
    /**
     * 返回指定日期的月的第一天
     * @param date   指定日期
     * @return
     * @author huanglt
     */
	public static String getFirstDayStrOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return getDateStr(getFirstDayOfMonth(calendar.getTime()),LINK_DISPLAY_DATE);
	}
    /**
     * 返回指定年月的月的第一天
     * @param year
     * @param month
     * @return
     * @author huanglt
     */
    public static Date getFirstDayOfMonth(Integer year, Integer month) {
        Calendar calendar = Calendar.getInstance();
        if (year == null) {
            year = calendar.get(Calendar.YEAR);
        }
        if (month == null) {
            month = calendar.get(Calendar.MONTH);
        }
        calendar.set(year, month-1, 1);
        return calendar.getTime();
    }
    /**
     * 返回指定年月的月的第一天
     * @param year
     * @param month
     * @return
     * @author huanglt
     */
    public static String getFirstDayOfMonthByStr(Integer year, Integer month) {
    	String firstDay = getDateStr(getFirstDayOfMonth(year,month),LINK_DISPLAY_DATE);
    	firstDay+= " 00:00:00";
        return firstDay;
    }
   
    /**
     * 返回指定日期的月的最后一天
     * @param
     * @param
     * @return
     * @author huanglt
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),
                     calendar.get(Calendar.MONTH), 1);
        calendar.roll(Calendar.DATE, -1);
        return calendar.getTime();
    }

    /**
     * 返回指定年月的月的最后一天
     * @param year
     * @param month
     * @return
     * @author huanglt
     */
    public static Date getLastDayOfMonth(Integer year, Integer month) {
        Calendar calendar = Calendar.getInstance();
        if (year == null) {
            year = calendar.get(Calendar.YEAR);
        }
        if (month == null) {
            month = calendar.get(Calendar.MONTH);
        }
        calendar.set(year, month-1, 1);
        calendar.roll(Calendar.DATE, -1);
        return calendar.getTime();
    }
    /**
     * 返回指定年月的月的第一天
     * @param year
     * @param month
     * @return
     * @author huanglt
     */
    public static String getLastDayOfMonthByStr(Integer year, Integer month) {
    	String lastDay = getDateStr(getLastDayOfMonth(year,month),LINK_DISPLAY_DATE);
    	lastDay+= " 23:59:59";
        return lastDay;
    }
    /**
     * 返回指定日期的上个月的最后一天
     * @param
     * @param
     * @return
     * @author huanglt
     */
    public static Date getLastDayOfLastMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),
                     calendar.get(Calendar.MONTH) - 1, 1);
        calendar.roll(Calendar.DATE, -1);
        return calendar.getTime();
    }
    
    /**
     * 返回指定日期的上个月第一天
     * @param date
     * @return
     */
    public static Date getFirstDayOfLastMonth(Date date) {
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

	/**
	 * 返回第一天
	 * @param date
	 * @return
	 * @author huanglt
	 */
    public static Date getFirstDayOfQuarter(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return getFirstDayOfQuarter(calendar.get(Calendar.YEAR),
                                    getQuarterOfYear(date));
    }

    public static String getFirstDayStr4Year(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Date firstDate = getFirstDayOfQuarter(calendar.get(Calendar.YEAR), getQuarterOfYear(date));
        return  getDateStr(firstDate,LINK_DISPLAY_DATE);
    }
    public static String getFirstDayStrOfQuarter(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Date firstDate = getFirstDayOfQuarter(calendar.get(Calendar.YEAR),
                                    getQuarterOfYear(date));
        return  getDateStr(firstDate,LINK_DISPLAY_DATE);
    }
    /**
     * 返回指定年季的季的第一天
     * @param year
     * @param quarter
     * @return
     * @author huanglt
     */
    public static Date getFirstDayOfQuarter(Integer year, Integer quarter) {
        Calendar calendar = Calendar.getInstance();
        Integer month = new Integer(0);
        if (quarter == 1) {
            month = 1 - 1;
        } else if (quarter == 2) {
            month = 4 - 1;
        } else if (quarter == 3) {
            month = 7 - 1;
        } else if (quarter == 4) {
            month = 10 - 1;
        } else {
            month = calendar.get(Calendar.MONTH);
        }
        return getFirstDayOfMonth(year, month);
    }



    /**
     * 返回指定年季的季的最后一天
     * @param year
     * @param quarter
     * @return
     * @author huanglt
     */
    public static Date getLastDayOfQuarter(Integer year, Integer quarter) {
        Calendar calendar = Calendar.getInstance();
        Integer month = new Integer(0);
        if (quarter == 1) {
            month = 3 - 1;
        } else if (quarter == 2) {
            month = 6 - 1;
        } else if (quarter == 3) {
            month = 9 - 1;
        } else if (quarter == 4) {
            month = 12 - 1;
        } else {
            month = calendar.get(Calendar.MONTH);
        }
        return getLastDayOfMonth(year, month);
    }
    
	/**
	 * @param date
	 * @return
	 * @author huanglt
	 */
    public static Date getLastDayOfQuarter(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return getLastDayOfQuarter(calendar.get(Calendar.YEAR),
                                   getQuarterOfYear(date));
    }
	/**
	 * 返回最后一日
	 * @param date
	 * @return
	 * @author huanglt
	 */
    public static Date getLastDayOfLastQuarter(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return getLastDayOfLastQuarter(calendar.get(Calendar.YEAR),
                                       getQuarterOfYear(date));
    }

    /**
     * 返回指定年季的上一季的最后一天
     * @param year
     * @param quarter
     * @return
     * @author huanglt
     */
    public static Date getLastDayOfLastQuarter(Integer year, Integer quarter) {
        Calendar calendar = Calendar.getInstance();
        Integer month = new Integer(0);
        if (quarter == 1) {
            month = 12 - 1;
        } else if (quarter == 2) {
            month = 3 - 1;
        } else if (quarter == 3) {
            month = 6 - 1;
        } else if (quarter == 4) {
            month = 9 - 1;
        } else {
            month = calendar.get(Calendar.MONTH);
        }
        return getLastDayOfMonth(year, month);
    }

    /**
     * 返回指定日期的季度
     * @param date
     * @return
     * @author huanglt
     */
    public static int getQuarterOfYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) / 3 + 1;
    }
    /**
     * 获取上一日
     * @param date
     * @return
     * @author huanglt
     */
    public static Date getBeforeDay(Date date) {
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(date);
    	calendar.add(Calendar.DATE, -1);
    	date = calendar.getTime();
    	return date;
    }

	public static Date getAfterDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, 1);
		date = calendar.getTime();
		return date;
	}
    /**
     * 获取上一周
     * @param date
     * @return
     * @author huanglt
     */
    public static Date getBeforeWeek(Date date) {
    	Calendar calendar = Calendar.getInstance();
    	calendar.setTime(date);
    	calendar.add(Calendar.DATE, -7);
    	date = calendar.getTime();
    	return date;
    }
    /**
     * 获取上一月
     * @param date
     * @return
     * @author huanglt
     */
    public static Date getBeforeMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, -1);
		date = calendar.getTime();
		return date;
	}

	public static Date getBeforeByDate(Date date,int num,int calendarType) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(calendarType, num);
		date = calendar.getTime();
		return date;
	}

    public static String getNextMonth(String dateStr) {
    	Date date = StringToDate(dateStr, LINK_DISPLAY_DATE_FULL);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, 1);
		date = calendar.getTime();
		return  getDateStr(date, LINK_DISPLAY_DATE_FULL);
	}
    
    public static String getBeforeMonthStr(String dateStr) {
    	Date date = StringToDate(dateStr, LINK_DISPLAY_DATE_FULL);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, -1);
		date = calendar.getTime();
		return  getDateStr(date, LINK_DISPLAY_DATE_FULL);
	}
    /**
     * 获取前/后几日
     * @param date 
     * @param num    正数 n天后； 负数 n天前
     * @param format 格式化日期
     * @return
     * @author huanglt
     */
    public static Date getFewDaysAgoOrLast(Date date,int num,String format) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, num);
		date = calendar.getTime();
		date = praseDateToDatePattern(date,format);
		return date;
	}
    /**
     * 获取上一日
     * @param
     * @return
     * @author huanglt
     */
    public static String getBeforeDayStr(String dateStr,String format) {
    	Date Date = StringToDate(dateStr,format);
    	Date beforeDate = getBeforeDay(Date);
		return getDateStr(beforeDate,format);
	}

	/**
	 * 获取下一日
	 * @param dateStr
	 * @param format
	 * @return
	 */
	public static String getAfterDayStr(String dateStr,String format) {
		Date Date = StringToDate(dateStr,format);
		Date beforeDate = getAfterDay(Date);
		return getDateStr(beforeDate,format);
	}
    /**
	 * 获取昨天
	 * @author huanglt
     * @return 
	 */
	public static String getYesterdayStr(String format){
		Date beforeDate = getBeforeDay(new Date());
		return getDateStr(beforeDate,format);
	}


    public static Date getgetFewMonthsAgoOrLast(Date date,int num) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, num);
		date = calendar.getTime();
		return date;
	}

	public static Date getFewMonthsAgoOrLast(Date date,int num,int calendarMonth) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(calendarMonth, num);
		date = calendar.getTime();
		return date;
	}

    /**  
     * 计算两个日期之间相差的天数  
     * @param smdate 较小的时间 
     * @param bdate  较大的时间 
     * @return 相差天数 
     * @throws ParseException  
     */    
    public static int daysBetween(Date smdate,Date bdate) {    
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");  
        try {
			smdate=sdf.parse(sdf.format(smdate));
	        bdate=sdf.parse(sdf.format(bdate));  
	        Calendar cal = Calendar.getInstance();    
	        cal.setTime(smdate);    
	        long time1 = cal.getTimeInMillis();                 
	        cal.setTime(bdate);    
	        long time2 = cal.getTimeInMillis();         
	        long between_days=(time2-time1)/(1000*3600*24);  
	        return Integer.parseInt(String.valueOf(between_days)); 
        } catch (ParseException e) {
			e.printStackTrace();
		} 
        return 0;
    }    
    /**
     * Timestamp转Date
     * @param tt
     * @return
     * @author huanglt
     */
    public static Date timestampToDate(Timestamp tt){  
        return new Date(tt.getTime());  
    }  
    
    /**
     * 获取执行日期的前几年/月/日/小时/分/秒
     * @param date
     * @param timeType
     * @param num
     * @return
     * @author chx
     */
    public static Date getPreOrAftDate(Date date,int timeType, int num){  
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		switch (timeType) {
		case Calendar.YEAR:
			calendar.add(Calendar.YEAR, num);
			break;
		case Calendar.MONTH:
			calendar.add(Calendar.MONTH, num);
			break;
		case Calendar.WEEK_OF_YEAR:
			calendar.add(Calendar.WEEK_OF_YEAR, num);
			break;	
		case Calendar.DAY_OF_YEAR:
			calendar.add(Calendar.DAY_OF_YEAR, num);
			break;
		case Calendar.HOUR:
			calendar.add(Calendar.HOUR, num);
			break;
		case Calendar.MINUTE:
			calendar.add(Calendar.MINUTE, num);
			break;
		case Calendar.SECOND:
			calendar.add(Calendar.SECOND, num);
			break;
		}
		return calendar.getTime();
    }  
    
    /**
     * 获取时间区间内，按梯度增加的最大时间
     * @param startTime
     * @param endTime
     * @param intervalSeconds  时间梯度（秒）
     * @return
     * @author chx
     */
    public static Date getLastRunTime(Date startTime,Date endTime, int intervalSeconds){  
    	Date tempDate = startTime;
    	while(endTime.after(tempDate)){
    		tempDate = getPreOrAftDate(tempDate, Calendar.SECOND, intervalSeconds);
    	}
    	return getPreOrAftDate(tempDate, Calendar.SECOND, 0-intervalSeconds);
    }
    
    
	/**
	 * 判断两个日期指定部分是否相等
	 * @param date1
	 * @param date2
	 * @param formatStr  时间格式的类型
	 * @return 
	 * @author chx
	 */
	public static boolean isDatePartEqual(Date date1, Date date2, String formatStr) {
		SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
		String s1 = sdf.format(date1);
		String s2 = sdf.format(date2);
		return s1.equals(s2);
	}
	/**
	 *  按小时获取完整的日期 
	 * @param timeStr 09:00
	 * @return
	 * @author huanglt
	 */
	public static Date getDateByHour(Date date ,String timeStr) {
		String dateStr = getDateStr(date,LINK_DISPLAY_DATE);
		return StringToDate(dateStr+" "+timeStr,LINK_DISPLAY_DATE_MINUTE);
	}
	/**
	 * 获取时间差
	 * @param stime
	 * @param etime
	 * @return
	 * @author huanglt
	 */
	public static long getTimeDif(Date stime,Date etime ) {
		return stime.getTime()-etime.getTime();
	}
	public static void main(String args[]) throws Exception{
		System.out.println(getLastDayOfMonth(new Date()));
	}
	
	/**
	 * 获取两个时间点之间的日期
	 * @param dBegin
	 * @param dEnd
	 * @return
	 */
	public static List<Date> findDates(Date dBegin, Date dEnd)  
	 {  
	  List<Date> lDate = new ArrayList<Date>();  
	  lDate.add(dBegin);  
	  Calendar calBegin = Calendar.getInstance();  
	  // 使用给定的 Date 设置此 Calendar 的时间  
	  calBegin.setTime(dBegin);  
	  Calendar calEnd = Calendar.getInstance();  
	  // 使用给定的 Date 设置此 Calendar 的时间  
	  calEnd.setTime(dEnd);  
	  // 测试此日期是否在指定日期之后  
	  while (dEnd.after(calBegin.getTime()))  
	  {  
	   // 根据日历的规则，为给定的日历字段添加或减去指定的时间量  
	   calBegin.add(Calendar.DAY_OF_MONTH, 1);  
	   lDate.add(calBegin.getTime());  
	  }  
	  return lDate;  
	 }

	 public static String secondsConvertToDateStr(int seconds){

		StringBuffer str = new StringBuffer();
		if (seconds > 0){
			//换成天
			int day=seconds/(60*60*24);
			//剩余的秒数换算为小时
			int hour=(seconds-(60*60*24*day))/3600;
			//剩余的秒数换算为分
			int minute=(seconds-60*60*24*day-3600*hour)/60;
			//剩余的秒数
			int second=seconds-60*60*24*day-3600*hour-60*minute;
			if (day > 0){
				str.append(day).append("天");
			}
			if (hour > 0){
				str.append(hour).append("小时");
			}
			if (minute >0) {
				str.append(minute).append("分钟");
			}
			if (second>0){
				str.append(second).append("秒");
			}
		}else {
			str.append(0 + "秒");
		}
		return str.toString();
	 }
	 
	 /**
	  * 获取星期几 {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
	  * @param date
	  * @return
	  */
	 public static Integer getWeek(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		Integer week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if(week_index<0){
			week_index = 0;
		} 
		return week_index;

	 }

	 public static Date min(Date date1, Date date2) {
	 	if (date1 == null) {
			return date2;
		} else if (date2 == null) {
	 		return null;
	 	}
	 	if (date1.before(date2)) {
	 		return date1;
	 	} else {
	 		return date2;
	 	}
	 }

	public static Date max(Date date1, Date date2) {
		if (date1 == null) {
			return date2;
		} else if (date2 == null) {
			return null;
		}
		if (date1.before(date2)) {
			return date2;
		} else {
			return date1;
		}
	}

    public static LocalDate dateToLocalDate(Date date) {
		if(null == date) {
			return null;
		}
		return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

    }

	public static LocalDateTime toLocalDateTime(Date date) {
	 	Instant instant = date.toInstant();
	 	ZoneId zoneId = ZoneId.systemDefault();
		LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
		return  localDateTime;
	}

	public static String toStringDateTime(Date date,String type) {
		SimpleDateFormat format = new SimpleDateFormat(type);
		String formateDate = format.format(date);
		return  formateDate;
	}

	public static Date toLocalDateTimeToDate(LocalDateTime localDateTime) {
		// 将此日期时间与时区相结合以创建 ZonedDateTime
		ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
		// 本地时间线LocalDateTime到即时时间线Instant时间戳
		Instant instant = zonedDateTime.toInstant();
		// UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间
		Date date = Date.from(instant);
		return  date;
	}

	public static List<String> getBetweenDates(String minDate, String maxDate) throws ParseException{
		List<String> listDate = new ArrayList<String>();
		Calendar startCalendar = Calendar.getInstance();
		Calendar endCalendar = Calendar.getInstance();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date startDate = df.parse(minDate);
		startCalendar.setTime(startDate);
		Date endDate = df.parse(maxDate);
		endCalendar.setTime(endDate);
		listDate.add(df.format(startCalendar.getTime()));
		while(true){
			startCalendar.add(Calendar.DAY_OF_MONTH, 1);
			if(startCalendar.getTimeInMillis() <= endCalendar.getTimeInMillis()){
				listDate.add(df.format(startCalendar.getTime()));
			}else{
				break;
			}
		}
		return listDate;
	}


	public static List<Date> getBetweenMinute(Date startDate, Date endDate) {
		List<Date> listDate = new ArrayList<Date>();
		Calendar startCalendar = Calendar.getInstance();
		Calendar endCalendar = Calendar.getInstance();
		startCalendar.setTime(startDate);
		endCalendar.setTime(endDate);
		listDate.add(startCalendar.getTime());
		while(true){
			startCalendar.add(Calendar.MINUTE, 1);
			if(startCalendar.getTimeInMillis() <= endCalendar.getTimeInMillis()){
				listDate.add(startCalendar.getTime());
			}else{
				break;
			}
		}
		return listDate;
	}

}